//
//  PPCalendarViewController.swift
//  PPKit
//
//  Created by xiaopin on 2021/12/5.
//  Copyright © 2021 sowell.com. All rights reserved.
//

import UIKit
import SwiftDate

/// 全屏弹出自定义日历
class PPCalendarViewController: XPBaseTableViewController {

    //MARK: 公开属性
    /// 选中：返回Date, yyyy-MM-dd格式值
    var selectedClosure:((Date,String)->())?
    /// 带有text的日期集合
    var texts:[PPCalendarTextModel]?
    /// 最小开始的年份
    var startYear = 2020
    /// 最大结束年份
    var endYear = 2050
    
    /// 当前时间
    lazy var currentDate = Date()
    /// 当前页面加载最小的时间
    var minDate = Date() - 1.months
    /// 当前页面加载最大的时间
    var maxDate = Date() + 1.months
    //MARK: 私有属性
    private var dataArray = [PPCalendarMonthModel]()
    
    //MARK: 懒加载
    lazy var calendar = Calendar.init(identifier: .gregorian)
    
    //MARK: 默认基类方法
    override var preferredStatusBarStyle: UIStatusBarStyle{
        return .default
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        initData()
        initNavigationBar()
        initSubViews()
        loadData()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
    }
}

//MARK: #重写基类方法#
extension PPCalendarViewController{
    /// 初始化数据
    override func initData() {
        super.initData()
    }
    
    /// 初始化导航栏
    override func initNavigationBar() {
        if let title = title{
            self.title = title
        }else{
            self.title = "PPCalendar"
        }
        super.initNavigationBar()
        
        navigationItem.leftBarButtonItem = UIBarButtonItem.init(image: UIImage(named: "close_7"), style: .plain, target: self, action: #selector(backAction))
    
        navigationItem.rightBarButtonItem = UIBarButtonItem.init(title: "MT_Date_Today".localized, style:.plain, target: self, action: #selector(todayAction(_:)))
        navigationItem.rightBarButtonItem?.tintColor = pp_color(.C159F48)
    }
    
    /// 初始化页面子控件视图
    override func initSubViews() {
        super.initSubViews()
        
        //let weekHeaders = ["日","一","二","三","四","五","六"]
        let weekHeaders = ["MT_Week_Sun_Abbr".localized,"MT_Week_Mon_Abbr".localized,"MT_Week_Tus_Abbr".localized,"MT_Week_Wen_Abbr".localized,"MT_Week_Thu_Abbr".localized,"MT_Week_Fri_Abbr".localized,"MT_Week_Sat_Abbr".localized]
        let weekHeaderView = UIView.init(frame: pp_frame(0, 0, pp_screen_width, 30))
        let itemWidth:CGFloat = pp_screen_width / 7.0
        for (i,value) in weekHeaders.enumerated() {
            let color = (i == 0 || i == 6) ? pp_color(.C159F48) : pp_color(.C999999)
            let label = UILabel.init(frame: pp_frame(i.f*itemWidth, 0, itemWidth, 30), text: value, textColor: color, fontSize: 12, weight: .regular, align: .center)
            weekHeaderView.addSubview(label)
        }
        view.addSubview(weekHeaderView)
        
        tableView.snp.remakeConstraints { m in
            m.top.equalTo(30)
            m.left.bottom.right.equalToSuperview()
        }
        tableView.dataSource = self
        tableView.delegate = self
        
        addPullDownAction()
        addPullUpAction()
    }
    
    override func loadData() {
        buildDataSource()
        tableView.reloadData()
    }
    
    /// 下拉获取前一个月的数据
    override func loadNewData() {
        endRefreshing()
        minDate = minDate - 1.months
        if minDate.year < startYear {return}
        
        var format:DateFormatStyle = .style_EN02
        let langCode = XPApplication.shared.language
        if langCode.contains("zh"){
            format = .style_CN02
        }
        
        let monthModel = PPCalendarMonthModel()
        monthModel.yearMonth = minDate.toString(format, langCode: langCode)
        monthModel.year = minDate.year
        monthModel.month = minDate.month
        for day in 1..<minDate.monthDays+1 {
            let date = Date(year: minDate.year, month: minDate.month, day: day, hour: 0, minute: 0)
            let dayModel = PPCalendarDayModel()
            dayModel.date = date
            dayModel.dateValue = date.toString(.style1)
            dayModel.value = day
            dayModel.weekday = date.weekday
            monthModel.days.append(dayModel)
        }
        dataArray.insert(monthModel, at: 0)
        tableView.reloadData()
        
    }
    
    /// 上拉获取后一个月的数据
    override func loadMoreData() {
        endRefreshing()
        maxDate = maxDate + 1.months
        if maxDate.year > endYear {return}
        
        var format:DateFormatStyle = .style_EN02
        let langCode = XPApplication.shared.language
        if langCode.contains("zh"){
            format = .style_CN02
        }
    
        let monthModel = PPCalendarMonthModel()
        monthModel.yearMonth = maxDate.toString(format, langCode: langCode)
        monthModel.year = maxDate.year
        monthModel.month = maxDate.month
        for day in 1..<maxDate.monthDays+1 {
            let date = Date(year: maxDate.year, month: maxDate.month, day: day, hour: 0, minute: 0)
            let dayModel = PPCalendarDayModel()
            dayModel.date = date
            dayModel.dateValue = date.toString(.style1)
            dayModel.value = day
            dayModel.weekday = date.weekday
            monthModel.days.append(dayModel)
        }
        dataArray.append(monthModel)
        tableView.reloadData()
    }
}

//MARK: #自定义方法#
extension PPCalendarViewController{
    /// 以当月为中心，先构建前后3个月数据
    func buildDataSource(){
        dataArray.removeAll()
        var format:DateFormatStyle = .style_EN02
        let langCode = XPApplication.shared.language
        if langCode.contains("zh"){
            format = .style_CN02
        }
        
        let prevModel = PPCalendarMonthModel()
        prevModel.yearMonth = minDate.toString(format, langCode: langCode)
        prevModel.year = minDate.year
        prevModel.month = minDate.month
        for day in 1..<minDate.monthDays+1 {
            let date = Date(year: minDate.year, month: minDate.month, day: day, hour: 0, minute: 0)
            let dayModel = PPCalendarDayModel()
            dayModel.date = date
            dayModel.dateValue = date.toString(.style1)
            dayModel.value = day
            dayModel.weekday = date.weekday
            dayModel.text = texts?.first(where: {$0.date == dayModel.dateValue})?.text ?? ""
            prevModel.days.append(dayModel)
        }
        dataArray.append(prevModel)
        
        let currentModel = PPCalendarMonthModel()
        currentModel.yearMonth = currentDate.toString(format, langCode: langCode)
        currentModel.year = currentDate.year
        currentModel.month = currentDate.month
        for day in 1..<currentDate.monthDays+1 {
            let date = Date(year: currentDate.year, month: currentDate.month, day: day, hour: 0, minute: 0)
            let dayModel = PPCalendarDayModel()
            dayModel.date = date
            dayModel.dateValue = date.toString(.style1)
            dayModel.value = day
            dayModel.weekday = date.weekday
            dayModel.text = texts?.first(where: {$0.date == dayModel.dateValue})?.text ?? ""
            currentModel.days.append(dayModel)
        }
        dataArray.append(currentModel)
        
        let nextModel = PPCalendarMonthModel()
        nextModel.yearMonth = maxDate.toString(format, langCode: langCode)
        nextModel.year = maxDate.year
        nextModel.month = maxDate.month
        for day in 1..<maxDate.monthDays+1 {
            let date = Date(year: maxDate.year, month: maxDate.month, day: day, hour: 0, minute: 0)
            let dayModel = PPCalendarDayModel()
            dayModel.date = date
            dayModel.dateValue = date.toString(.style1)
            dayModel.value = day
            dayModel.weekday = date.weekday
            dayModel.text = texts?.first(where: {$0.date == dayModel.dateValue})?.text ?? ""
            nextModel.days.append(dayModel)
        }
        dataArray.append(nextModel)
       
    }

    /// 获取指定月份的行高
    func getRowsHeight(_ month:PPCalendarMonthModel) -> CGFloat{
        if month.days.count == 0 {return 0}
        var rows = 0
        for (i,day) in month.days.enumerated() {
            if i == 0{
                rows = 1
                continue
            }
            if day.weekday == 1 {
                rows += 1
            }
        }
        return (10 + 41 * rows).f
    }
    
    func show(in vc:UIViewController){
        let navc = XPNavigationController(rootViewController: self)
        navc.modalTransitionStyle = .coverVertical
        navc.modalPresentationStyle = .overFullScreen
        vc.present(navc, animated: true)
    }
}

//MARK: #事件通知#
extension PPCalendarViewController{
    override func backAction() {
        dismiss(animated: true)
    }
    
    func todayAction(_ sender:Any){
        if let index = dataArray.firstIndex(where: { return $0.year == currentDate.year && $0.month == currentDate.month}) {
            tableView.scrollToRow(at: IndexPath(row: 0, section: index), at: .middle, animated: true)
        }
        selectedClosure?(Date(), Date().toString(.style1))
        backAction()
    }
}

//MARK: #委托代理#
extension PPCalendarViewController:UITableViewDelegate,UITableViewDataSource{
    //MARK: 标准UITableView代理
    func numberOfSections(in tableView: UITableView) -> Int {
        return dataArray.count
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return getRowsHeight(dataArray[indexPath.section])
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = PPCalendarDayCell.cell(tableView: tableView)
        let model = dataArray[indexPath.section]
        cell.configureData(model)
        cell.selectedClosure = { [weak self] (date,value) in
            self?.selectedClosure?(date,value)
            self?.backAction()
        }
        return cell
    }
    
    //MARK: 追加HeaderFooterView
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 35
    }
    
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let header = PPCalendarHeaderView.header(tableView: tableView)
        header.titleLabel.text = dataArray[section].yearMonth
        return header
    }
    
    func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        return CGFloat.leastNonzeroMagnitude
    }
    
    func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        return nil
    }

}
